<?php

namespace App\Modules\LuckDraw\Strategy;

use App\Modules\LuckDraw\Award\AwardFactory;
use App\Modules\LuckDraw\Models\AwardPoolModel;
use Illuminate\Support\Facades\Redis;

class RandStrategy implements StrategyInterface {
    private $_name = "rand";
    private $_luckId;
    private $_userId;
    private $_ext;
    private $_pool;
    private $_randRedisKey;

    public function __construct(int $luckId, int $userId, ?object $ext, object $pool){
        $this->_luckId = $luckId;
        $this->_userId = $userId;
        $this->_ext = $ext;
        $this->_pool = $pool;
        $this->_randRedisKey = sprintf('STRATEGY:RAND:DRAW:%s:POOL:%s', $luckId, $pool->id);
    }

    public function pool():?object{
        return $this->_pool;
    }

    public function poolId():?int{
        return $this->pool()->id;
    }

    public function name():?string{
        return $this->_name;
    }

    public function run(int $num) : ?array {
        if ($num <= 0) {
            return [];
        }
        $awardPool = $this->_getPoolData();
        $awardArr = [];
        $total = $this->_getTotalNum($awardPool);
        for ($i = 0; $i<$num; $i++) {
            $pre = 0;
            $rand = rand(1, $total);
            foreach ($awardPool as $award) {
                if ($rand <= $pre + $award->num && $rand > $pre) {
                    $k = $award->type . '-' . $award->id . '-' . $award->time;
                    if (isset($awardArr[$k])) {
                        $awardArr[$k]->num++; //数量加
                        break;
                    }
                    //转化成对象
                    $awardObj = AwardFactory::get(
                        $this->_luckId,
                        $this->_userId,
                        $award->type,
                        $award->id,
                        $award->time,
                        $award->price
                    );
                    if ($awardObj == null){
                        return null;
                    }
                    $awardArr[$k] = $awardObj;
                    break;
                }
                $pre = $pre + $award->num;
            }
        }

        return array_values($awardArr);
    }

    function _getTotalNum($awards) {
        $total = 0;
        foreach ($awards as $award) {
            $total += $award->num;
        }
        return $total;
    }

    //根据奖池id，获取奖池数据
    function _getPoolData(): ?array{
        return json_decode($this->pool()->pool);
    }

    //获取奖池数据
    function getPoolData(): ?array{
        return json_decode($this->pool()->pool);
    }

    //抽奖失败的回滚
    public function rollBack() {
        // TODO: Implement rollBack() method.
    }
    public function delPoolRedis():?bool {
        return true;
    }

    public function upAwardStrategy(array $poolDatas):?array{
        return [];
    }

    public static function clearCacheByPoolId(int $luckId, array $userList, int $poolId): bool {
        // TODO: Implement clearCacheByPooId() method.
        return true;
    }
}
